#ifndef SLOTRESULT_H
#define SLOTRESULT_H

#include "lib.h"

#pragma warning( disable: 4786 )

#include <vector>
#include <map>

using namespace std;

typedef vector<uint8> ResultNotes;

class SpinLine
{
    public:

	    SpinLine()
        {
            lineid = 0;
            basepayoutamount = 0;
            jackpot = false;
            payouttypeid = 0;
            totallinepayoutamount = 0;
            totalmultiplier = 1;
        }
  
        ~SpinLine()
        {
            m_resultNotes.clear();
        }

        void addNote(uint8 noteid)
        {
            m_resultNotes.push_back(noteid);
        }

        uint8 getNote(uint8 nIndex) const
        {
            uint8 noteid = 255;

            if ( nIndex < m_resultNotes.size() )
            {
                noteid = m_resultNotes[nIndex];
            }
            else
            {
                ASSERT(false);
            }

            return noteid;
        }

        uint8 getNoteCount() const
        {
            return m_resultNotes.size();
        }

        ///  The line number. 
        uint8 lineid;           
        /// @brief the number of cents won.
        int32 basepayoutamount;
        /// @brief   Did they win the jackpot?
        bool8 jackpot;          
        /// @brief The pay table result. 
        uint8 payouttypeid;    
        
        int32 totalmultiplier;

        int32 totallinepayoutamount;

        ResultNotes m_resultNotes;
};

class BonusGame
{
	public:
		uint8 bonusgametype;
		uint8 bonusgameindex;
		int32 basepayoutamount;
		int32 totalmultiplier;
		int32 totalbonuspayoutamount;
		int32 freespins;
		bool8 bSaved;
		bool8 m_overridegamenum;
		int64 m_newgamenum;
        ResultNotes m_resultNotes;

		BonusGame ()
		{
			bonusgametype = 0;
			bonusgameindex = 0;
			basepayoutamount = 0;
			totalmultiplier = 0;
			totalbonuspayoutamount = 0;
			freespins = 0;
			bSaved = false;
			m_overridegamenum = false;
			m_newgamenum = 0;

		}
		~BonusGame()
		{
            m_resultNotes.clear();
		}

		void overrideGameNum(int64 gamenum)
		{
			m_overridegamenum = true;
			m_newgamenum = gamenum;
		}

        void addNote(uint8 noteid)
        {
            m_resultNotes.push_back(noteid);
        }


        uint8 getNote(uint8 nIndex) const
        {
            uint8 noteid = 255;

            if ( nIndex < m_resultNotes.size() )
            {
                noteid = m_resultNotes[nIndex];
            }
            else
            {
                ASSERT(false);
            }

            return noteid;
        }

        uint8 getNoteCount() const
        {
            return m_resultNotes.size();
        }

};

class SlotScatter
{
    public:
	    SlotScatter()
        {
            scatterid = 0;
            scatterposition = 0;
            basepayoutamount = 0;
            jackpot = false;
            payouttypeid = 0;
            totalscatterpayoutamount = 0;
            totalmultiplier = 1;
        }
  
        ~SlotScatter()
        {
            m_resultNotes.clear();
        }

        void addNote(uint8 noteid)
        {
            m_resultNotes.push_back(noteid);
        }


        uint8 getNote(uint8 nIndex) const
        {
            uint8 noteid = 255;

            if ( nIndex < m_resultNotes.size() )
            {
                noteid = m_resultNotes[nIndex];
            }
            else
            {
                ASSERT(false);
            }

            return noteid;
        }

        uint8 getNoteCount() const
        {
            return m_resultNotes.size();
        }

        /// @brief The unique scatter id.
        uint8 scatterid;
        ///  The line number. 
        int32 scatterposition;           
        /// @brief the number of cents won (before the multiplier).
        int32 basepayoutamount;
        /// @brief the bonus multiplier.
        int32 totalmultiplier;
        /// @brief the number of cents won after applying the multiplier.
        int32 totalscatterpayoutamount;
        /// @brief   Did they win the jackpot?
        bool8 jackpot;          
        /// @brief The pay table result. 
        uint8 payouttypeid;  
        /// @brief
        int32 freespins;
        
        ResultNotes m_resultNotes;

};

class SlotSpin
{
	public:
		SlotSpin();
		~SlotSpin();

		void setStops(uint8 stopCount, uint8 *stops);

        void setPayoutAmount(uint8 lineid, int32 basepayoutamount, int32 totalmultiplier, int32 totallinepayout, bool8 jackpot, uint8 payouttypeid);

        void setJackpotAmount(uint8 lineid, int32 jackpotamount);

        void addLine(uint8 lineid);

        void setBet(uint8 bet);

        void setSpinSent(bool8 flag);
        bool8 isSpinSent();

        void setSpinSaved(bool8 flag);
        bool8 isSpinSaved();

        void setSpinComplete(bool8 flag);
        bool8 isSpinComplete();

        uint8 getSpinLineCount() const;
        SpinLine *getSpinLineAt(uint8 index);
        SpinLine *getSpinLineByLineId(uint8 lineid);

        SlotScatter* addScatter( int32 scatterposition, int32 payoutamount, int32 totalmultiplier, bool8 jackpot, uint8 payouttypeid, int32 freespins );
        void clearScatters();
        uint8 getNumScatters() const;
        SlotScatter* getScatter(uint8 nIndex) const;

        uint8 getBet() const;

        int32 getMultibankBet() const;
        void setMultibankBet(int32 bet);

        int32 getMultibankPayout() const;
        void setMultibankPayout(int32 payout);

        bool8 getJackpot();

        uint16 getTotalBet() const;
        int32 getTotalPayoutAmount();

        void setGameNum(int64 gamenum);
        int64 getGameNum() const;

        uint8 getStopCount() const;
        const uint8 *getStops() const;

        uint8 getBonusGameType() const;
        void setBonusGameType(uint8 bonusGameType);

        BonusGame* addBonusGame(uint8 bonusgametype,uint8 bonusgameindex,int32 basepayoutamount,int32 totalmultiplier,int32 totalbonuspayoutamount,int32 freespins,int64 overridegamenum,bool8 bSaved = false);
        void clearBonusGames();
        uint8 getNumBonusGames() const;
        BonusGame* getBonusGame(uint8 nIndex) const;

        int32 getTotalBonusPayoutAmount();
        int32 getTotalSpinPayoutAmount();

        bool8 getAutoplay();
        void  setAutoplay(bool8 bAutoplay);

        uint8 getGameModeId();
        void  setGameModeId(uint8 m_nGameModeId);

        int32 getNumSpinsRemaining();
        void  setNumSpinsRemaining( int32 numSpinsRemaining);

        void  addWheelViewIcon(uint8 nReel, uint8 nRow, uint8 nIcon);
        uint8 getWheelViewIcon(uint8 nReel, uint8 nRow);

		void setNumRows(uint8 nRows);		// Needed for games with more than 3 rows (i.e. Football Frenzy)
		uint8 getNumRows();					// Needed for games with more than 3 rows (i.e. Football Frenzy)

    private:
        typedef vector<SpinLine *> SpinLines;
        typedef vector<SlotScatter *> Scatters;
        typedef vector<BonusGame *> BonusGames;
        typedef map<uint16,uint8> WheelViewIcons;


        SpinLine *findSpinLine(uint8 lineid) const;
        BonusGame *findBonusGame(uint8 bonusGameNum) const;

        SpinLines  m_spinLines;
        BonusGames m_bonusGames;
        Scatters   m_scatters;
        WheelViewIcons m_mapWheelViewIcons;

        uint8 m_bet;               // The bet in credits.
        int32 m_multibankBet;      // The amount contributed to multi-bank.
        int32 m_multibankPayout;   // The amount won via multi-bank.
        uint8 m_stopCount;         // The number of stops.
        uint8 *m_stops;            // The actual wheel stops.
        int64 m_gameNum;           // The game number.  Only set after it is saved.
        uint8 m_bonusGameType;
        bool8 m_spinComplete;      // A flag indicating this spin is complete and ready for saving.
        bool8 m_spinSaved;         // true if the spin is saved.
        bool8 m_spinSent;          // true if the spin has been sent to the client
        bool8 m_bAutoplay;         // true if the client used the autoplayer for this spin.
        uint8 m_nGameModeId;        
        int32 m_nNumSpinsRemaining;

		uint8 m_nNumRows;		   // Needed for games with more than 3 rows (i.e. Football Frenzy)

};



#endif

